﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CNShapes;
using System.Drawing;
using BobcatMultiTouch;

namespace CNPageEditor
{
    /// <summary>
    /// A base class for actions that draw shapes derived from the 
    /// ShapeBase_RectangularBounds class. These shapes have a start 
    /// point and an end point.
    /// </summary><remarks>
    /// You derive an action class from this class and implement:
    /// 
    /// - getShape() to return a new instance of the concrete
    ///              shape being managed by your action.
    ///              
    /// - getDescription() to return the string description of
    ///                    the action.
    /// </remarks>
    public abstract class ActionBase_DrawRectangularBoundsShape : Action
    {
        #region Abstract methods

        /// <summary>
        /// Returns the instance of the shape (derived from ShapeBase_RectangularBounds
        /// that this action manages).
        /// </summary>
        public abstract ShapeBase_RectangularBounds getShape();

        #endregion

        #region Public methods

        /// <summary>
        /// Called to set up the action.
        /// </summary>
        public override void initialize()
        {
            // We create the shape and add it to the picture...
            m_Shape = getShape();
            m_Page.addShape(m_Shape, getActionOrigin());
        }

		/// <summary>
		/// Called when the action becomes inactive.
		/// </summary>
		public override void deactivate()
		{
		}

		/// <summary>
        /// Undo is supported for this action.
        /// </summary>
        public override bool supportsUndo()
        {
            return true;
        }

        /// <summary>
        /// Shape drawing is repeatable, i.e. we go back to drawing the same shape after
        /// this action has completed.
        /// </summary>
        public override bool isRepeatable()
        {
            return true;
        }

        /// <summary>
        /// Removes the box from the picture.
        /// </summary>
        public override void undo()
        {
            m_Page.removeShape(m_Shape.ID, getActionOrigin());
        }

        /// <summary>
        /// Re-adds the box to the picture.
        /// </summary>
        public override void redo()
        {
            m_Page.addShape(m_Shape, getActionOrigin());
        }

        /// <summary>
        /// Called when we get a touch-down event.
        /// </summary>
        public override void onTouchDown(TouchArgs touchArgs)
        {
            // We set the pen width relative to the current zoom factor...
            float fPenWidth = m_Shape.getPenWidth() / m_PageViewerControl.ZoomFactor;
            m_Shape.setPenWidth(fPenWidth, getActionOrigin());

            // We translate the client coords into shape-coords and set the top-left
            // corner of the box to where the touch occured...
            PointF shapePoint = m_PageViewerControl.clientPointToShapePoint(touchArgs.ClientPosition);
            m_Shape.setStartPoint(shapePoint, getActionOrigin());
        }

        /// <summary>
        /// Called when we get a touch-move event.
        /// </summary>
        public override void onTouchMove(TouchArgs touchArgs)
        {
            // We set the bottom-right corner of the box to be the current position...
            PointF shapePoint = m_PageViewerControl.clientPointToShapePoint(touchArgs.ClientPosition);
            m_Shape.setEndPoint(shapePoint, getActionOrigin());
        }

        /// <summary>
        /// Called when we get a touch-up event.
        /// </summary>
        public override void onTouchUp(TouchArgs touchArgs)
        {
            // You've finished drawing the box...
            m_Shape.editCompleted(getActionOrigin());
            raiseActionCompletedEvent();
        }

        #endregion

        #region Protected data
        
        // The shape we are managing...
        ShapeBase_RectangularBounds m_Shape = null;

        #endregion
    }
}
